<?php

/**
 * Put all _GET variables in array to easier accessing them later
 *
 * @return array()
 */
function extractGet()
{
	$get = array();
	foreach ($_GET as $key => $val)
	{
		$get[ $key ] = $val;
	}

	return $get;
}


/**
 * Put all _POST variables in array to easier accessing them later
 *
 * @return array()
 */
function extractPost()
{
	$post = array();
	foreach ($_POST as $key => $val)
	{
		$post[ $key ] = $val;
	}

	return $post;
}

/**
 * Helper to quicker send error messages
 *
 * @param string $errorMessage
 * @param array $params
 * @return string
 */
function jsonError($errorMessage, Array $params = [])
{
	$result["success"] = 'false';
	$result["reason"] = vsprintf($errorMessage, $params);

	return json_encode($result);
}

function jsonSuccess($successParam, $successContent)
{
	$result["success"] = 'true';
	$result[ $successParam ] = $successContent;

	return json_encode($result);
}

function jsonSuccessDie($successParam, $successContent)
{
	echo jsonSuccess($successParam, $successContent);
	die();
}

function jsonErrorDie($errorMessage, Array $params = [])
{
	echo jsonError($errorMessage, $params);
	die();
}

// NOTE: Delay is in seconds!!!!
function getDateWithDelay($delay)
{
	$todayDate = date("Y-m-d g:i a"); // current date
	$currentTime = time($todayDate); //Change date into time


	//echo "<br>".$currentTime;
	//Add one hour equavelent seconds 60*60

	return date("Y-m-d H:i:s", ($currentTime + $delay));

}

function getCurrentDate()
{
	return date("Y-m-d g:i a"); // current date
}

// Lock time = 5 min
function isUserLocked($time)
{
	if ( is_null($time) )
	{
		return false;
	}
	$currentTime = time(getCurrentDate());
	$fiveMins = 60 * 5;
	// User is locked
	if ( $currentTime < ($time + $fiveMins) )
	{
		return true;
	} else
	{
		return false;
	}
}

function getRoleName($role_id)
{
	$array = [0 => 'admin', 1 => 'kanbanmaster', 2 => 'Product Owner', 3 => 'Developer'];

	return $array[ $role_id ];
}

function getPossibleUserRoles($userId)
{
	// Add all possible roles.
	$roleIds = R::getAll("SELECT id FROM role WHERE id IN (SELECT role_id FROM role_user WHERE user_id = :user_id)", [':user_id' => $userId]);

	$idArray = array();
	foreach ($roleIds as $key => $value)
	{
		$idArray[] = $value["id"];
	}

	return $idArray;
}

function deactivetUserGroup($user_id, $group)
{
	$nonActive = json_decode($group->nonActiveUsers);
	array_push($nonActive, $user_id);

	return json_encode($nonActive);
}

function activateUserGroup($user_id, $group)
{
	$nonActive = json_decode($group->nonActiveUsers);
	$key = array_search($user_id, $nonActive);
	unset($nonActive[ $key ]);

	return json_encode(array_values($nonActive));
}

function addDeveloperGroup($user_id, $group)
{
	$devs = json_decode($group->developers);
	array_push($devs, $user_id);

	return json_encode(array_unique($devs));
}

function isInBeans($id, $beans)
{
	foreach ($beans as $bean)
	{
		if ( $id == $bean->id ) return true;
	}

	return false;
}
function getDaysDiff($dt1, $dt2) {
	$current_date = DateTime::createFromFormat("Y-m-d H:i:s", $dt1);
	$project_date = DateTime::createFromFormat("Y-m-d H:i:s", $dt2);
	return $current_date->diff($project_date)->format("%a");
}
function logCardMoveWIP($card)
{
	$message = "Wip by card " . $card->id;
	$moved_day = date_diff(new DateTime(R::isoDateTime()), new DateTime($card->project->created_date))->format("%d");

	$log = R::dispense('log');
	$log->type = 'cardmoveWIP';
	$log->cardId = $card->id;
	$log->message = $message;
	$log->date = R::isoDateTime();
	$log->moved_day = $moved_day;
	R::store($log);
}

function logCardMove($card, $column, $prev_column)
{
	$message = 'Card ' . $card->title . ' was moved from ' . $column->name . ' to ' . $prev_column->name;
	$moved_day = getDaysDiff(date("Y-m-d H:i:s"), $card->project->created_date) - 2 ;
	//get prevoius move
	$card_logs = $card->with('order by moved_day ASC')->ownLogList;
	$prev_moved_day = 0;
	foreach ($card_logs as $log)
	{
		if ( $log->moved_day < $moved_day )
			$prev_moved_day = $log->moved_day;
		if ( $log->moved_day == $moved_day )
			break;
	}

	$log = R::dispense('log');
	$log->type = 'cardmove';
	$log->cardId = $card->id;
	$log->prevColumnId = $prev_column->id;
	$log->currentColumnId = $column->id;
	$log->message = $message;
	$log->date = R::isoDateTime();
	$log->moved_day = $moved_day;
	$log->prev_moved_day = $prev_moved_day;
	$log->projectId = $card->project->id;
	R::store($log);
}

function getLogsMovedAtDay($day, $project_id)
{
	$logs =  R::findAll('log', 'type="cardmove" AND moved_day = ? AND prev_moved_day <= ? AND project_id = ? ORDER BY date ', array($day, $day, $project_id));
	//get only top columns without subcolumns
	return array_filter($logs, function($var) {
		return  R::load('column', $var->prevColumnId)->name != R::load('column', $var->currentColumnId)->name ||
				$var->prevColumnId == $var->currentColumnId;
	});
}

function getTopLevelColumns($board_id) {
	return R::findAll('column', 'board_id = ? group by name order by position', [$board_id]);
}


/**
 * 
 * HELPER METHODS FOR CALCULATING AVERAGE TIME
 *
 */
/*
 * Function that converts seconds to months, days, hours and minutes
 */
function secondsToStringTime($time){
    $months = floor($time/60/60/24/30);
    $time = $time % (60*60*24*30);
    $days = floor($time/60/60/24);
    $time = $time % (60*60*24);
    $hours = floor($time/60/60);
    $time = $time % 60*60;
    $mins = floor($time / 60);
    return (($months > 0)?$months . " months":""). (($days > 0)?$days . " days":""). " $hours hours and $mins minutes";
}
/*
 * Function receives all cards and then calculates average developing time
 */
function calculateAverageTime($cards, $leftColumn, $rightColumn){

    $sumTime = 0;
    $i = 0;
    foreach ($cards as $card){
        $col = R::load( 'column', $card->column_id);

        if($col->position > $rightColumn->position){
            $startTime = getMoveDate($card->id, $leftColumn, true);
            $endTime = getMoveDate($card->id, $rightColumn, false);

            //echo "$endTime vs $startTime \n";
            if(!is_null($startTime) && !is_null($endTime)){
                //echo "\n - " . $startTime ." : " . $endTime . "($card->title)";
                $time = strtotime($endTime) - strtotime($startTime);
                $sumTime += $time;
                $i++;
            }
        }

    }
    if($i > 0){
        return $sumTime/$i;
    }
    else{ 
        return 0;
    }
}

/*
* Function retrieves move time from database, if last parameter is true, then it retrieves start time, otherwise finish time of developement
*/
function getMoveDate($cardId, $column, $forStart){

   if($forStart){
       $prevColumn = R::findOne( 'column', 'board_id = ? AND position < ? ORDER BY position DESC', array($column->board_id, $column->position));
       if(is_null($prevColumn)){
           $card = R::load('card', $cardId);
           return $card->date_created;
       }
       $prevColId = $prevColumn->id;
       $curColId = $column->id;
   }
   else{
       $prevColId = $column->id;
       $nextColumn = R::findOne( 'column', 'board_id = ? AND position > ? ORDER BY position ASC', array($column->board_id, $column->position));
       $curColId = ($nextColumn == NULL)?NULL:$nextColumn->id;
   }
   //echo "\n" . $cardId . " : " . $prevColId . " : " . $curColId ."  -- ";
   $log = R::findOne('log', 'type = "cardmove" AND card_id = ? AND prev_column_id = ? AND current_column_id = ?', array($cardId, $prevColId, $curColId));
   if(is_null($log)){
       return null;
   }
   //echo "LOG " . $log->date;
   return $log->date;
}

// WIP violation

function getCardWIPViolationLogs($cards){
    $filteredAndOrderedLogs = array();
    foreach ($cards as $card){
        
        $logs = R::find('log','card_id = ? AND type = ? ORDER BY current_column_id',[$card->id, "cardmoveWIP"]);
        if(!empty($logs)){
            if(!isset($filteredAndOrderedLogs[$card->id])){
                $filteredAndOrderedLogs[$card->id] = array();
            }
            $filteredAndOrderedLogs[$card->id] = $filteredAndOrderedLogs[$card->id] + $logs;
        }
    }
    if(count($filteredAndOrderedLogs) == 0){
        return "";
    }
    $toPrint = "";
    foreach ($filteredAndOrderedLogs as $cardId => $logs){
        $card = R::load('card',$cardId);
        $toPrint .= "<h4>$card->title (#$card->id)</h4>";
        $toPrint .= "<table style='border: 1px solid black;'>";
        $toPrint.= "<tr>"
                    . "<td style='width: 400px'><b>Message</b><td>"
                    . "<td style='width: 200px'><b>Date</b></td>"
                    . "<td style='width: 200px'><b>Column</b></td>"
                    . "<td style='width: 200px'><b>Username</b></td>"
                    . "</tr>";
        foreach($logs as $log){
            //print_r($log);
            $column = R::load('column', $log->current_column_id);
            $user = R::load('user', $log->producer_id);
            $toPrint.= "<tr>"
                    . "<td style='width: 400px'>$log->message<td>"
                    . "<td style='width: 200px'>$log->date</td>"
                    . "<td style='width: 200px'>". (is_null($column->subcolumn) ? $column->name : $column->subcolumn) ."</td>"
                    . "<td style='width: 200px'>$user->email</td>"
                    . "</tr>";
        }
        $toPrint .= "</table>";
        
    }
    return $toPrint;
}

